/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package registry;

import java.net.InetAddress;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import registry.RegistryEvents.ServerAddedEvent;
import shared.FileInfo;
import shared.PicRegistry;
import shared.QueryResponse;
import shared.ServerInfo;

/**
 *
 * @author Eric
 */
public class PicRegistryController implements PicRegistry {

    private final Map <InetAddress, ServerInfo> servers;
    private List<RegistryListener> listeners;
    private RegistryRefresher refresher;
    private Thread refresherThread;

    public PicRegistryController() {
        servers = new HashMap();
        listeners = new ArrayList();
        refresher = new RegistryRefresher(this);
        refresherThread = new Thread(refresher);




    }
    
    protected void startRefresher()
    {
        refresherThread.start();
        Timer timer = new Timer();
        timer.schedule(new TimerTask(){

            @Override
            public void run() {
                
                Map<InetAddress,ServerInfo> serverMap=null; 
                synchronized(servers)
                {                    
                    if (servers.size() > 0)
                    {
                        serverMap = new HashMap<InetAddress,ServerInfo>(servers);
                        
                    }
                }
                if (serverMap!= null && serverMap.size() > 0)
                    refresher.updatedList(serverMap);
            }
        }, 0, 4000);
    }

    public void removeServers (List<InetAddress> removeList)
    {
        for (InetAddress address : removeList)
        {
            synchronized (servers)
            {
                servers.remove(address);
            }
        }
    }

    public void addPicRegistryListener(RegistryListener l)
    {
        if (l!=null)
            listeners.add(l);
    }
    private void fireServerAddedEvent(ServerAddedEvent e)
    {
       for (RegistryListener l : listeners)
           l.serverAdded(e);
    }
    public void registerServer(ServerInfo info) {
        if (servers.containsKey(info.getAddress()));
            servers.remove(info.getAddress());
        servers.put(info.getAddress(), info);

         fireServerAddedEvent(new ServerAddedEvent(info));
    }


    public QueryResponse fileQuery(String filename) throws RemoteException {
        Set<InetAddress> addresses = servers.keySet();
        QueryResponse response = new QueryResponse();
        for(InetAddress address : addresses)
        {
            ServerInfo currentServerInfo = servers.get(address);
            List<FileInfo> fileInfoList = currentServerInfo.getFileList();
            for(FileInfo fileInfo : fileInfoList)
            {
                if(fileInfo.getFileName().equals(filename))
                {
                   response.setFileInfo(fileInfo);
                   response.getServers().add(currentServerInfo);
                }
            }
        }
        return response;
    }

    public synchronized List<ServerInfo> getAvailableServerList() throws RemoteException {
        List<ServerInfo> serverList = new ArrayList<ServerInfo>();
        Set<InetAddress> keySet = servers.keySet();
        for(InetAddress addr : keySet)
        {
            serverList.add(servers.get(addr));
        }
        return serverList;
    }
}
